#include <As/Http/EvHttpAdapter.h>

#include <QDebug>

#include <evhttp.h>
#include <event.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>

const short  SERVER_BACKLOG    = 128;

namespace As {

void EvHttpAdapter::evhttp_callback(evhttp_request *req, void* arg) {
    qDebug() << "in EvHttpAdapter::evhttp_callback()";
}

EvHttpAdapter::EvHttpAdapter(const QString &host, int port,
			     bool startListen, QObject *parent) :
    AbstractHttpAdapter(parent),
    m_host(host),
    m_port(port)
{
    m_ev_base = (event_base *) event_init();
    m_ev_http = evhttp_new(m_ev_base);
    if (startListen) {
	listen();
    }
    qDebug() << this;
}

EvHttpAdapter::~EvHttpAdapter() {

}

void EvHttpAdapter::listen() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in sa;
    int on = 1;

    sa.sin_family      = AF_INET;
    sa.sin_port        = htons(m_port);
    sa.sin_addr.s_addr = inet_addr(m_host.toAscii().data());

//    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) == -1)) {
//        qDebug() << "Failed to set socket option.";
//    }
    if (bind(sock, (const sockaddr*) &sa, sizeof(sa)) == -1) {
        qDebug() << "Failed to bind socket.";
    }
    if (::listen(sock, SERVER_BACKLOG) == -1) {
        qDebug() << "Failed to listen.";
    }
    if (evhttp_accept_socket(m_ev_http, sock) == -1) {
        qDebug() << "evhttp_accept_socket() failed.";
    }

    // Set evhttp callback.
    evhttp_set_gencb(
                m_ev_http,
                (void (*)(evhttp_request *, void *)) &EvHttpAdapter::evhttp_callback,
                (void *) this);

    // Start event loop.
    event_base_dispatch(m_ev_base);
}

void EvHttpAdapter::stopListen() {

}

void EvHttpAdapter::response(As::HttpResponse resp) {

}

}
